package com.yeyks.commonReference.service.consumer.impl;

import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yeyks.common.base.PageInfo;
import com.yeyks.common.constants.ConfigKey;
import com.yeyks.common.constants.MessageTemplate;
import com.yeyks.common.constants.RechargeRecordStatus;
import com.yeyks.common.constants.consumer.UserInviteRelationTypeConstant;
import com.yeyks.common.dto.RechargeRecordDTO;
import com.yeyks.common.em.MessageNoticeType;
import com.yeyks.common.em.RechangeRecordEnum;
import com.yeyks.common.em.UserBillType;
import com.yeyks.common.em.UserMemberCardBillType;
import com.yeyks.common.em.consumer.UserInviteRelationTypeEnum;
import com.yeyks.common.em.pay.PayAttach;
import com.yeyks.common.em.pay.PayTypeEnum;
import com.yeyks.common.em.vip.VipCardTypeEnum;
import com.yeyks.common.exception.ServiceException;
import com.yeyks.common.param.RechargeRecordQueryParam;
import com.yeyks.common.utils.*;
import com.yeyks.common.utils.arithmetic.Lottery;
import com.yeyks.common.utils.base.PhoneUtil;
import com.yeyks.commonReference.append.pay.PayService;
import com.yeyks.commonReference.service.config.ConfigService;
import com.yeyks.commonReference.service.config.RechargeConfigService;
import com.yeyks.commonReference.service.consumer.MessageNoticeTemplateService;
import com.yeyks.commonReference.service.consumer.UserCouponInfoService;
import com.yeyks.commonReference.service.consumer.UserMemberCardService;
import com.yeyks.config.dal.domain.RechargeConfig;
import com.yeyks.consumer.dal.dao.RechargeRecordMapper;
import com.yeyks.consumer.dal.domain.*;
import com.yeyks.consumer.dto.RecommendDetailDTO;
import com.yeyks.consumer.param.BagGiftPayParam;
import com.yeyks.consumer.param.PayParam;
import com.yeyks.consumer.param.UserMemberCard.UserMemberCardAddAmountParam;
import com.yeyks.consumer.service.*;
import com.yeyks.vip.dal.domain.MemberCardSellRelationLevel;
import com.yeyks.vip.service.MemberCardSellRelationLevelService;
import com.yeyks.vip.service.MemberCardSellRelationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * <p>
 * 充值记录表 服务实现类
 * </p>
 *
 * @author yun
 * @since 2019-06-25
 */
@Slf4j
@Service
public class RechargeRecordServiceImpl extends ServiceImpl<RechargeRecordMapper, RechargeRecord> implements RechargeRecordService {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private PayService payService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private UserAccountOverviewService overviewService;
    @Autowired
    private UserCouponInfoService userCouponService;
    @Autowired
    private MessageNoticeService noticeService;
    @Autowired
    private MessageNoticeTemplateService templateService;
    @Autowired
    private UserMemberCardService userMemberCardService;
    @Autowired
    private RechargeConfigService rechargeConfigService;
    @Autowired
    private MemberCardDetailService memberCardDetailService;
    @Autowired
    private UserInviteRelationService userInviteRelationService;
    @Autowired
    private MemberCardSellRelationLevelService memberCardSellRelationLevelService;
    @Autowired
    private UserMakerService userMakerService;
    @Autowired
    private MemberCardSellRelationService memberCardSellRelationService;

    //白名单支付金额
    private static final Integer whitePayAmount = 10;

    /**
     * 处理黑鱼礼包充值回调
     *
     * @param orderNo 订单号
     * @param flag    是否成功
     */
    @Override
    @Transactional
    public void paySmallBlackFishSpreeCallback(String orderNo, Boolean flag) {
        //通过订单号查询订单
        RechargeRecord rechargeRecord = baseMapper.selectOrderByOrderNo(orderNo);
        int status = RechargeRecordStatus.postPay;
        //成功，并发放佣金
        if (flag) {
            //发放券
            userCouponService.giveSmallBlackFishSpreeSuccess(orderNo);
//            makerCommission(rechargeRecord);
        } else {
            status = RechargeRecordStatus.payFailed;
            //回滚券
            userCouponService.giveSmallBlackFishSpreeFail(orderNo);
        }
        //修改订单的状态
        Integer res = baseMapper.updateByOrderNoAndStatus(orderNo, status);
        if (res != 1) {
            log.info("充值更新订单状态失败");
        }
    }

    //发放创客佣金
    @Override
    public void makerCommission(RechargeRecord rechargeRecord) {
        //发放一级佣金
        Map<String, String> map = commission(rechargeRecord);
        //写入一级佣金消息
        commissionMessage(map, rechargeRecord.getPayAmount());
        //发放二级佣金
        Map<String, String> twoMap = commissionTwo(rechargeRecord);
        //写入二级佣金消息
        commissionTwoMessage(twoMap, rechargeRecord.getPayAmount());
    }

    //发放创客佣金
    public void makerCommissionV340(RechargeRecord rechargeRecord) {
        //发放一级佣金
        Map<String, String> map = commissionV430(rechargeRecord);
        //写入一级佣金消息
        commissionMessageV430(map, rechargeRecord.getPayAmount());
    }

    Map<String, Integer> makerAmountMap = JSONUtil.toBean("{'1,1':3000,'1,2':9900,'1,3':19800,'2,1':3500,'2,2':19800,'2,3':39600,'3,1':4000,'3,2':29700,'3,3':59400}", Map.class);
    Map<Integer, String> makerNameMap = JSONUtil.toBean("{'1':'白银推广员','2':'黄金推广员','3':'钻石推广员'}", Map.class);

    private Map<String, String> commissionV430(RechargeRecord rechargeRecord) {
        Map<String, String> map = new HashMap<>();
        try {
            //通过邀请码获取邀请码对应的用户
            UserInfo userInfo = userInfoService.selectUserByCode(rechargeRecord.getInviteId());
            if (userInfo == null) {
                return null;
            }
            //存储用户关系
            userInviteRelationService.createUserInviteRelation(rechargeRecord.getUserId(), userInfo.getId(), UserInviteRelationTypeEnum.MAKER.getValue());
            //创客信息
            UserMaker userMaker = userMakerService.getOne(
                    new QueryWrapper<UserMaker>()
                            .eq(UserMaker.USER_ID, userInfo.getId())
                            .last("limit 1")
            );
            UserMaker userMaker_invite = userMakerService.getOne(
                    new QueryWrapper<UserMaker>()
                            .eq(UserMaker.USER_ID, rechargeRecord.getUserId())
                            .last("limit 1")
            );
            //佣金
            Integer amount = makerAmountMap.get(
                    new StringJoiner(",")
                            .add(String.valueOf(userMaker.getMakerLevel()))
                            .add(String.valueOf(userMaker_invite.getMakerLevel()))
                            .toString()
            );
            if (Objects.isNull(amount)) {
                throw new ServiceException("推广佣金获取失败");
            }
            Boolean isSuccess = overviewService.addAmount(amount, userInfo.getId(), UserBillType.COMMSION.value(), UserBillType.COMMSION.desc(), UserInviteRelationTypeConstant.INVITE_PAY);
            if (!isSuccess) {
                log.info("佣金增加余额失败userId = {}, amount = {}", userInfo.getId(), amount);
            }
            //添加经验
            userMakerService.update(
                    new UpdateWrapper<UserMaker>()
                            .setSql(String.format("%s=%s+1", UserMaker.EXPERIENCE, UserMaker.EXPERIENCE))
                            .eq(UserMaker.ID, userMaker.getId())
            );
            if (CompareUtil.compare(userMaker.getMakerLevel(), 3) < 0 && CompareUtil.compare(userMaker.getExperience(), 99) >= 0) {
                userMakerService.update(
                        new UpdateWrapper<UserMaker>()
                                .set(UserMaker.EXPERIENCE, 0)
                                .setSql(String.format("%s=%s+1", UserMaker.MAKER_LEVEL, UserMaker.MAKER_LEVEL))
                                .eq(UserMaker.ID, userMaker.getId())
                );
            }
            //更新邀请等级
            if (CompareUtil.compare(userMaker.getMakerInviteLevel(), userMaker_invite.getMakerLevel()) < 0) {
                userMakerService.update(
                        new UpdateWrapper<UserMaker>()
                                .set(UserMaker.MAKER_INVITE_LEVEL, userMaker_invite.getMakerLevel())
                                .eq(UserMaker.ID, userMaker.getId())
                );
            }
            UserInfo orderUser = userInfoService.getById(rechargeRecord.getUserId());
            if (orderUser == null) {
                return null;
            }
            String makerLevelName = makerNameMap.get(String.valueOf(userMaker_invite.getMakerLevel()));
            if (StrUtil.isBlank(makerLevelName)) {
                makerLevelName = "白银推广员";
            }
            map.put("makerLevelName", makerLevelName);
            map.put("makerLevel", String.valueOf(userMaker_invite.getMakerLevel()));
            map.put("getAmount", String.valueOf(amount));
            map.put("phone", orderUser.getPhone());
            map.put("userId", String.valueOf(userInfo.getId()));
            return map;
        } catch (Exception e) {
            log.error("发放佣金异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        return map;
    }

    private void commissionMessageV430(Map<String, String> messMap, Integer payAmount) {
        try {
            if (messMap == null || messMap.size() == 0) {
                return;
            }
            String userId = messMap.get("userId");
            Map<String, Object> param = new HashMap<>();
            param.put("makerLevelName", messMap.get("makerLevelName"));
            param.put("makerLevel", messMap.get("makerLevel"));
            param.put("phone", PhoneUtil.replace(messMap.get("phone")));
            param.put("payAmount", FormatUtils.fenToYuan(payAmount));
            String getAmount = messMap.get("getAmount");
            int intAmount = Integer.valueOf(getAmount);
            param.put("getAmount", FormatUtils.fenToYuan(intAmount));
            Map<String, String> map = templateService.commonValue(param, MessageTemplate.USER_MAKER_AMOUNT);
            int res = noticeService.activieyCreateAndSave(map, Integer.valueOf(userId), MessageNoticeType.activity_commission.value());
            if (res != 1) {
                log.info("写入佣金消息异常");
            }
        } catch (Exception e) {
            log.error("写入佣金消息异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
    }

    private void commissionTwoMessage(Map<String, String> twoMap, Integer payAmount) {
        try {
            if (twoMap == null || twoMap.size() == 0) {
                return;
            }
            String userId = twoMap.get("userId");
            //您邀请的好友【${onePhone}】成功邀请好友【${phone}】充值${payAmount}元， 成功获取${getAmount}元佣金
            Map<String, Object> param = new HashMap<>();
            param.put("onePhone", PhoneUtil.replace(twoMap.get("onePhone")));
            param.put("phone", PhoneUtil.replace(twoMap.get("phone")));
            param.put("payAmount", FormatUtils.fenToYuan(payAmount));
            String getAmount = twoMap.get("getAmount");
            int intAmount = Integer.valueOf(getAmount);
            param.put("getAmount", FormatUtils.fenToYuan(intAmount));
            Map<String, String> map = templateService.commonValue(param, MessageTemplate.COMMISSION_TWO);
            int res = noticeService.activieyCreateAndSave(map, Integer.valueOf(userId), MessageNoticeType.activity_commission.value());
            if (res != 1) {
                log.info("写入佣金消息异常");
            }
        } catch (Exception e) {
            log.error("写入佣金消息异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
    }

    private Map<String, String> commissionTwo(RechargeRecord rechargeRecord) {
        Map<String, String> map = new HashMap<>();
        try {
            //查找父用户
            UserInfo userInfo = userInfoService.selectUserByCode(rechargeRecord.getInviteId());
            if (userInfo == null) {
                return null;
            }
            UserInviteRelation userInviteRelation = userInviteRelationService.getOne(
                    new QueryWrapper<UserInviteRelation>()
                            .eq(UserInviteRelation.USER_ID, userInfo.getId())
                            .eq(UserInviteRelation.TYPE, UserInviteRelationTypeEnum.MAKER.getValue())
                            .last("limit 1")
            );
            if (Objects.isNull(userInviteRelation)) {
                return null;
            }
            Integer parentId = userInviteRelation.getParentId();
//            //通过父用户的id查询父用户下的单
////            RechargeRecord parentRecord = rechargeRecordMapper.selectByUserId(userInfo.getId());
//            RechargeRecord parentRecord = baseMapper.selectUserId(userInfo.getId(), 2, RechangeRecordEnum.MEMBER_CARD_RECHANGE_VIP.value());
//            if (parentRecord == null) {
//                return null;
//            }
//            //通过父用户的订单查询父用户的父用户
//            UserInfo parentUserInfo = userInfoService.selectUserByCode(parentRecord.getInviteId());
//            if (parentUserInfo == null) {
//                return null;
//            }
//            //获取佣金比例
//            Integer commissionRate = getCommissionRate(2);
//            //父用户的父用户获取佣金
//            Integer amount = FormatUtils.amountToRate(rechargeRecord.getPayAmount(), commissionRate);
            //佣金
            Integer amount = 2000;
            Boolean isSuccess = overviewService.addAmount(amount, parentId, UserBillType.COMMSION.value(), UserBillType.COMMSION.desc(), UserInviteRelationTypeConstant.INVITE_PAY);
            if (!isSuccess) {
                log.info("佣金增加余额失败userId = {}, amount = {}", parentId, amount);
            }
            //查找下单用户
            UserInfo orderUser = userInfoService.getById(rechargeRecord.getUserId());
            if (orderUser == null) {
                return null;
            }
            map.put("getAmount", String.valueOf(amount));
            map.put("phone", orderUser.getPhone());
            map.put("onePhone", userInfo.getPhone());
            map.put("userId", String.valueOf(parentId));
            return map;
        } catch (Exception e) {
            log.error("发放佣金异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        return map;

    }

    /**
     * 处理会员卡充值回调
     *
     * @param orderNo 订单号
     * @param flag    是否成功
     */
    @Override
    public void payCardCallback(String orderNo, Boolean flag) {
        //通过订单号查询订单
        RechargeRecord rechargeRecord = baseMapper.selectOrderByOrderNo(orderNo);
        int status = RechargeRecordStatus.postPay;
        //成功，增加会员卡余额, 并增加会员卡明细
        if (flag) {
            addUserMemberCard(rechargeRecord);
            //增加一条记录
            insertMemberCardDetail(rechargeRecord);
        } else {
            status = RechargeRecordStatus.payFailed;
        }
        //修改订单的状态
        Integer res = baseMapper.updateByOrderNoAndStatus(orderNo, status);
        if (res != 1) {
            log.info("会员卡充值更新订单状态失败");
        }
    }

    private void insertMemberCardDetail(RechargeRecord rechargeRecord) {
        try {
            Integer cardType = VipCardTypeEnum.getCardTypeByRechargeRecordTypeValueThrowE(rechargeRecord.getType());
            UserMemberCard userMemberCard = userMemberCardService.getUserMemberCard(rechargeRecord.getUserId(), cardType);
            if (Objects.isNull(userMemberCard)) {
                log.warn("该用户没有绑卡{}", rechargeRecord.getUserId());
                return;
            }
            Map<String, Object> param = Maps.newHashMap();
            int payAmount = rechargeRecord.getPayAmount();
            RechargeConfig byPayAmount = rechargeConfigService.getByPayAmount(rechargeRecord.getUserId(), payAmount, VipCardTypeEnum.getCardTypeByRechargeRecordTypeValue(rechargeRecord.getType()));
            if (byPayAmount != null) {
                payAmount += byPayAmount.getGiveAmount();
            }
            param.put("amount", FormatUtils.fenToYuan(payAmount));
            param.put("remainAmount", FormatUtils.fenToYuan(userMemberCard.getRemainGiveAmount() + userMemberCard.getRemainPayAmount()));
            Map<String, String> map = templateService.commonValue(param, MessageTemplate.CARD_PAY);
            MemberCardDetail detail = new MemberCardDetail();
            detail.setUserId(rechargeRecord.getUserId());
            detail.setContent(map.get("content"));
            detail.setIconUrl(map.get("iconUrl"));
            detail.setCreateTime(new Date());
            detail.setCardType(cardType);
            memberCardDetailService.insert(detail);
        } catch (Exception e) {
            log.error("增加会员卡余额详情异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
    }

    private void addUserMemberCard(RechargeRecord rechargeRecord) {
        try {
            //获取赠送金额
            int giveAmount = 0;
            RechargeConfig rechargeConfig = rechargeConfigService.getByPayAmount(rechargeRecord.getUserId(), rechargeRecord.getPayAmount(), VipCardTypeEnum.getCardTypeByRechargeRecordTypeValue(rechargeRecord.getType()));
            if (rechargeConfig != null) {
                giveAmount = rechargeConfig.getGiveAmount();
            }
            UserMemberCardAddAmountParam userMemberCardAddAmountParam = new UserMemberCardAddAmountParam();
            userMemberCardAddAmountParam.setUserId(rechargeRecord.getUserId());
            userMemberCardAddAmountParam.setPayAmount(rechargeRecord.getPayAmount());
            userMemberCardAddAmountParam.setGiveAmount(giveAmount);
            userMemberCardAddAmountParam.setType(UserMemberCardBillType.PAY.value());
            userMemberCardAddAmountParam.setRemark(UserMemberCardBillType.PAY.desc());
            userMemberCardAddAmountParam.setOrderNo(rechargeRecord.getOrderNo());
            userMemberCardAddAmountParam.setCardType(VipCardTypeEnum.getCardTypeByRechargeRecordTypeValueThrowE(rechargeRecord.getType()));
            Boolean flag = userMemberCardService.addAmount(userMemberCardAddAmountParam);
            if (!flag) {
                log.error("增加会员卡余额异常");
            }
        } catch (Exception e) {
            log.error("增加会员卡余额异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
    }

    /**
     * 通过邀请码获取该邀请码对应推广人数
     *
     * @param inviteCode
     * @return
     */
    @Override
    public Integer selectCountByInviteId(String inviteCode) {
        return baseMapper.selectCountByInviteId(inviteCode);
    }

    /**
     * 获取佣金明细
     *
     * @param userId
     * @param type
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public List<RecommendDetailDTO> detailList(Integer userId, String type, Integer pageNo, Integer pageSize) {
        List<RecommendDetailDTO> recommendDetailDTOS = new ArrayList<>();
        try {
            PageInfo pageInfo = PageInfo.of(pageNo, pageSize);
            Map<String, Object> param = new HashMap<>();
            param.put("userId", userId);
            param.put("types", Splitters.splitToString(type, Splitters.COMMA));
            param.put("offset", pageInfo.getOffset());
            param.put("limit", pageInfo.getLimit());
            List<MessageNotice> lists = noticeService.detailList(param);
            if (lists == null) {
                return recommendDetailDTOS;
            }
            recommendDetailDTOS = ObjectConvertUtil.convertList(lists, RecommendDetailDTO.class);
        } catch (Exception e) {
            log.error("分页获取佣金明细通知消息失败{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        return recommendDetailDTOS;
    }

    /**
     * 推广规则
     *
     * @return
     */
    @Override
    public List<String> rule() {
        List<String> lists = Lists.newArrayList();
        try {
            String value = configService.getValue(ConfigKey.RECOMMEND_RULE);
            log.info(value);
            lists = Splitters.splitToString(value, Splitters.ENTER);
            return lists;

        } catch (Exception e) {
            lists.add("1. 推广期间，长按保存二维码分享给好友或者直接邀请好友直接扫描二维码即可参与活动");
            lists.add("2. 好友进入推广活动，输入手机号支付10元完成参与活动");
            lists.add("3. 好友支付十元，用户即可获得7元佣金，同时好友获得一张30元及以上优惠券一张或免单券一张");
            lists.add("4. 用户获得的佣金支持绑定银行卡提现");
            lists.add("5. 好友获得优惠券可在预订酒店时使用");
            lists.add("6. 若有疑问请拨打客服热线：400-8263595 客服时间：9：00 - 17:00");
            lists.add("7. 夜鱼快宿保留该活动最终解释权");
        }
        return null;
    }

    /**
     * 获取活动链接
     *
     * @return
     */
    @Override
    public Object getUrl() {
        try {
            String value = configService.getValue(ConfigKey.RECOMMEND_URL);
            return JSONObject.parseObject(value);
        } catch (Exception e) {
            log.error("获取推广url异常{}", e.getLocalizedMessage());
            Map<String, String> map = Maps.newHashMap();
            map.put("tuiUrl", "https://kuaisutest.chengguokj.com/activity/promotionMe");
            map.put("promoteUrl", "https://kuaisutest.chengguokj.com/h5/promotePlay/app");
            map.put("commissionUrl", "https://kuaisutest.chengguokj.com/h5/cmsFaq/app");
            map.put("purchaseVipCard", "https://kuaisutest.chengguokj.com/activity/purchaseVipCard");
            return map;
        }
    }

    /**
     * 判断用户是否已经充值
     *
     * @param userInfo
     * @return
     */
//    @Override
//    public Boolean isRecharge(Integer userId) {
//        List<RechargeRecord> rechargeRecords = rechargeRecordMapper.selectByUserIdAndStatus(userId, 2, RechangeRecordEnum.TEN.value());
//        if (rechargeRecords == null || rechargeRecords.size() < 1) {
//            rechargeRecords = rechargeRecordMapper.selectByUserIdAndStatus(userId, 2, RechangeRecordEnum.BAG_GIFT.value());
//            if (rechargeRecords == null || rechargeRecords.size() < 1) {
//                return false;
//            }
//        }
//        return rechargeRecords.size() >= getRechargeCount();
//    }
    @Override
    public Boolean isRecharge(UserInfo userInfo) {
        //查询白名单，判断该手机号是否在白名单,在白名单返回false(未充值)true(已充值)
        if (configService.checkWhiteList(userInfo.getPhone())) {
            return false;
        }
        QueryWrapper<RechargeRecord> wrapper = new QueryWrapper<>();
        wrapper.eq(RechargeRecord.USER_ID, userInfo.getId()).eq(RechargeRecord.STATUS, RechargeRecordStatus.postPay).in(RechargeRecord.TYPE, Lists.newArrayList(RechangeRecordEnum.TEN.value(), RechangeRecordEnum.BAG_GIFT.value()));
        List<RechargeRecord> rechargeRecords = baseMapper.selectList(wrapper);
        return rechargeRecords != null && rechargeRecords.size() >= 1;
    }

    /**
     * 创建充值记录
     *
     * @param rechargeRecord
     * @return
     */
    @Override
    public Boolean insert(RechargeRecord rechargeRecord) {
        Date date = new Date();
        rechargeRecord.setCreatedTime(date);
        rechargeRecord.setUpdatedTime(date);
        return baseMapper.insert(rechargeRecord) == 1;
    }

    /**
     * 通过充值订单id获取充值订单信息
     *
     * @param id
     * @return
     */
    @Override
    public RechargeRecord selectById(Integer id) {
        return baseMapper.selectById(id);
    }

    /**
     * 更新充值订单信息
     *
     * @param rechargeRecord
     * @return
     */
    @Override
    public Integer update(RechargeRecord rechargeRecord) {
        rechargeRecord.setUpdatedTime(new Date());
        return baseMapper.updateById(rechargeRecord);
    }

    /**
     * 推广描述图片
     *
     * @return
     */
    @Override
    public Map<String, Object> desc() {
        try {
            String value = configService.getValue(ConfigKey.RECOMMEND_DESC);
            if (ArgumentsCheckUtil.strIsNull(value)) {
                return ImmutableMap.of("url", "https://yeyu-kuaisu.oss-cn-hangzhou.aliyuncs.com/image/myrec3%403x.jpg");
            }
            return ImmutableMap.of("url", value);
        } catch (Exception e) {
            log.error("获取推广url异常{}", e.getLocalizedMessage());
            e.printStackTrace();
            return ImmutableMap.of("url", "https://yeyu-kuaisu.oss-cn-hangzhou.aliyuncs.com/image/myrec3%403x.jpg");
        }
    }

    /**
     * 推广活动详情
     *
     * @return
     */
    @Override
    public Map<String, List<String>> activityDetail() {
        try {
            String value = configService.getValue(ConfigKey.RECOMMEND_ACTIVITY_DETAIL);
            if (ArgumentsCheckUtil.strIsNull(value)) {
                return defaultActivityDetail();
            }
            return (Map<String, List<String>>) JSONObject.parse(value);
        } catch (Exception e) {
            log.error("获取推广url异常{}", e.getLocalizedMessage());
            e.printStackTrace();
            return defaultActivityDetail();
        }

    }

    /**
     * 推广大礼包充值
     *
     * @param userInfo
     * @param bagGiftPayParam
     * @param ip
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object bagGiftPay(UserInfo userInfo, BagGiftPayParam bagGiftPayParam, String ip) {
        RechargeRecord rechargeRecord = baseMapper.selectById(bagGiftPayParam.getOrderId());
        if (rechargeRecord == null) {
            throw new ServiceException("该充值订单不存在");
        }
        rechargeRecord.setPaymentMethod(PayTypeEnum.getValue(bagGiftPayParam.getType()));
        rechargeRecord.setUpdatedTime(new Date());
        int update = baseMapper.updateById(rechargeRecord);
        if (update != 1) {
            throw new ServiceException("更新订单支付方式失败");
        }
        //给用户发大礼包优惠券(满300减30券2张、满200减20券4张、满100减10券6张)
        userCouponService.giveBagGift(userInfo.getId(), rechargeRecord.getOrderNo());
        return pay(bagGiftPayParam, ip, rechargeRecord);
    }

    private Map<String, Object> pay(BagGiftPayParam bagGiftPayParam, String ip, RechargeRecord rechargeRecord) {
        Map<String, Object> map = new HashMap<>();
        map.put("orderNo", rechargeRecord.getOrderNo());
        if (payService.doPay(map, PayAttach.BAG_GIFT_PAY.desc(), bagGiftPayParam.getType(), rechargeRecord.getOrderNo(), rechargeRecord.getPayAmount(), bagGiftPayParam.getOpenId(), ip, null, null)) {
            return map;
        }
//        try {
//            //支付宝
//            if (PayTypeEnum.ALIPAY.desc().equals(bagGiftPayParam.getType())) {
//                HashMap<String, String> attachMap = new HashMap<>();
//                attachMap.put("payType", PayAttach.BAG_GIFT_PAY.desc());
//                attachMap.put("payMethod", PayTypeEnum.ALIPAY.desc());
//                String payInfo = alipayService.unifiedPay(rechargeRecord.getOrderNo(), rechargeRecord.getPayAmount(), alipayAppProperties.getNewNotifyUrl(), JSONUtil.toJsonStr(attachMap));
//                map.put("payInfo", payInfo);
//                return map;
//            }
//            //微信支付
//            if (PayTypeEnum.WXPAY.desc().equals(bagGiftPayParam.getType())) {
//                HashMap<String, String> attachMap = new HashMap<>();
//                attachMap.put("payType", PayAttach.BAG_GIFT_PAY.desc());
//                attachMap.put("payMethod", PayTypeEnum.WXPAY.desc());
//                WxPayParam wxPayParam = new WxPayParam(bagGiftPayParam.getType(), null, rechargeRecord.getPayAmount(), rechargeRecord.getOrderNo(), ip, wxProperties.getNewNotifyUrl(), "APP", JSONUtil.toJsonStr(attachMap));
//                Map<String, String> wxMap = wxLoginService.appDisposePay(wxPayParam);
//                String payInfo = JSONObject.toJSONString(wxMap);
//                map.put("payInfo", payInfo);
//                return map;
//            }
//            //jsapi
//            if (PayTypeEnum.GZH.desc().equals(bagGiftPayParam.getType()) || PayTypeEnum.XCX.desc().equals(bagGiftPayParam.getType())) {
//                if (ArgumentsCheckUtil.strIsNull(bagGiftPayParam.getOpenId())) {
//                    throw new ServiceException("openId必传");
//                }
//                //小程序和公众号用的是同一个商户订单号体系,商户订单号不能重复,故同一修改订单号,添加后缀xcx
//                String orderNoNew = rechargeRecord.getOrderNo();
//                if (PayTypeEnum.XCX.desc().equals(bagGiftPayParam.getType())) {
//                    orderNoNew += PayTypeEnum.XCX.desc();
//                }
//                HashMap<String, String> attachMap = new HashMap<>();
//                attachMap.put("payType", PayAttach.BAG_GIFT_PAY.desc());
//                attachMap.put("payMethod", PayTypeEnum.WXPAY.desc());
//                WxPayParam wxPayParam = new WxPayParam(bagGiftPayParam.getType(), bagGiftPayParam.getOpenId(), rechargeRecord.getPayAmount(), rechargeRecord.getOrderNo(), ip, wxProperties.getNewNotifyUrl(), "JSAPI", JSONUtil.toJsonStr(attachMap));
//                Map<String, Object> unifiedOrder = wxLoginService.disposeUnifiedOrder(wxPayParam);
//                map.put("payInfo", unifiedOrder);
//                return map;
//            }
//        } catch (ServiceException e) {
//            throw new ServiceException(e.getMessage());
//        } catch (Exception e) {
//            log.info("推广大礼包支付异常{}", Arrays.toString(e.getStackTrace()));
//            throw new ServiceException("支付异常");
//        }
        return null;
    }

    /**
     * 用户生成推广大礼包订单
     *
     * @param price
     * @param userInfo
     * @return
     */
    @Override
    public Map<String, Object> createBagGiftOrder(Integer price, UserInfo userInfo, String inviteId) {
//        RechargeRecord record = rechargeRecordMapper.selectOne(new QueryWrapper<RechargeRecord>()
//                .eq(RechargeRecord.USER_ID, userInfo.getId()).eq(RechargeRecord.TYPE, 3).eq(RechargeRecord.STATUS, 1));
//        if (null == record) {
//            record = getNewRechargeRecord(price, userInfo, inviteId);
//            rechargeRecordMapper.insert(record);
//        }
        RechargeRecord record = getNewRechargeRecord(price, userInfo, inviteId);
        baseMapper.insert(record);
        return ImmutableMap.of("orderId", record.getId());
    }

    @Override
    public List<RechargeRecordDTO> queryByParam(RechargeRecordQueryParam param) {

        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<RechargeRecordDTO> list = this.baseMapper.queryByParam(param);
        return list;
    }

    @Override
    public int queryCount(RechargeRecordQueryParam param) {
        return this.baseMapper.queryByParam(param).size();
    }

    @Override
    public List<RechargeRecordDTO> queryExportByParam(RechargeRecordQueryParam param) {
        return this.baseMapper.queryByParam(param);
    }

    //创建创客订单（创客身份记录）
    @Override
    public RechargeRecord getNewRechargeRecord(Integer payAmount, UserInfo userInfo, String inviteId) {
        String orderNo = IdWorkerUtil.nextStrId();
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setOrderNo(orderNo);
        //白名单判断
        if (configService.checkWhiteList(userInfo.getPhone())) {
            rechargeRecord.setPayAmount(whitePayAmount);
        } else {
            rechargeRecord.setPayAmount(payAmount);
        }
        rechargeRecord.setInviteId(inviteId);
        rechargeRecord.setType(RechangeRecordEnum.BAG_GIFT.value());
        rechargeRecord.setOrderDesc(RechangeRecordEnum.BAG_GIFT.desc());
        rechargeRecord.setUserId(userInfo.getId());
        rechargeRecord.setStatus(RechargeRecordStatus.prePay);
        Date date = new Date();
        rechargeRecord.setCreatedTime(date);
        rechargeRecord.setUpdatedTime(date);
        return rechargeRecord;
    }

    private Map<String, List<String>> defaultActivityDetail() {
        Map<String, List<String>> map = Maps.newHashMap();
        List<String> list = Lists.newArrayList();
        list.add("活动期间，支付10元随机获得30元到免单特权一次。");
        list.add("优惠券及免单特权使用方法：打开【夜鱼快宿】APP，选择地址、输入酒店金额、发送抢单，点击预订酒店，即可享受免单特权或使用优惠券。");
        list.add("活动期间，邀请其他用户参与此活动，即可获得佣金3元。");
        list.add("您邀请的好友邀请其他用户参与该活动,您可立即获得6元佣金。");
        list.add("获得免单特权用户，在下单时自动使用免单特权，入住200元以下客房直接免单，超过200元房型则抵扣200元房费。");
        list.add("优惠券及免单特权的有效期3个月。");
        list.add("本次活动每位用户仅限参与一次。");
        list.add("最终解释权归夜鱼快宿所有。");
        map.put("recommend", list);
        List<String> list2 = Lists.newArrayList();
        list2.add("1. 活动期间，支付10元获得价值200元小黑鱼优惠券礼包一份");
        list2.add("2. 打开小黑鱼大礼包即获得多张优惠券组合");
        list2.add("3. 优惠券使用方法：打开【夜鱼快宿】APP，选择地址、输入酒店金额、发送抢单，点击预订酒店，即可使用优惠券");
        list2.add("4. 活动期间，邀请其他用户参与此活动，即可获得佣金3元");
        list2.add("5. 您邀请的好友邀请其他用户参与该活动,您可立即获得6元佣金");
        list2.add("6. 获得优惠券的用户，请在优惠券有效期内下单预订酒店，否则优惠券过期则作废处理");
        list2.add("7. 最终解释权归夜鱼快宿所有");
        map.put("gift", list2);
        return map;
    }

    private int getRechargeCount() {
        try {
            String value = configService.getValue(ConfigKey.RECHARGE_COUNT);
            return Integer.valueOf(value);
        } catch (Exception e) {
            log.error("获取充值上线异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        return 1;
    }

    private void commissionMessage(Map<String, String> messMap, Integer payAmount) {
        try {
            if (messMap == null || messMap.size() == 0) {
                return;
            }
            String userId = messMap.get("userId");
            //【${phone}】充值${payAmount}元， 成功获取${getAmount}
            Map<String, Object> param = new HashMap<>();
            param.put("phone", PhoneUtil.replace(messMap.get("phone")));
            param.put("payAmount", FormatUtils.fenToYuan(payAmount));
            String getAmount = messMap.get("getAmount");
            int intAmount = Integer.valueOf(getAmount);
            param.put("getAmount", FormatUtils.fenToYuan(intAmount));
            Map<String, String> map = templateService.commonValue(param, MessageTemplate.COMMISSION);
            int res = noticeService.activieyCreateAndSave(map, Integer.valueOf(userId), MessageNoticeType.activity_commission.value());
            if (res != 1) {
                log.info("写入佣金消息异常");
            }
        } catch (Exception e) {
            log.error("写入佣金消息异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
    }

    private void sendCouponInfo(RechargeRecord rechargeRecord) {
        try {
            Integer lottery = Lottery.lottery(configService.getProbability());
            if (!userCouponService.getRecommendCoupon(rechargeRecord.getUserId(), lottery, rechargeRecord.getOrderNo())) {
                log.warn("获取推广优惠券失败");
            }
        } catch (ServiceException e) {
            log.error("推广获取随机券异常{}", e.getMessage());
        } catch (Exception e) {
            log.error("推广获取随机券异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
    }

    private Map<String, String> commission(RechargeRecord rechargeRecord) {
        Map<String, String> map = new HashMap<>();
        try {
            //通过邀请码获取邀请码对应的用户
            UserInfo userInfo = userInfoService.selectUserByCode(rechargeRecord.getInviteId());
            if (userInfo == null) {
                return null;
            }
            //存储用户关系
            userInviteRelationService.createUserInviteRelation(rechargeRecord.getUserId(), userInfo.getId(), UserInviteRelationTypeEnum.MAKER.getValue());

//            //获取佣金比例
//            Integer commissionRate = getCommissionRate(1);
//            //获取佣金
//            Integer amount = FormatUtils.amountToRate(rechargeRecord.getPayAmount(), commissionRate);
            //佣金
            Integer amount = 1000;
            Boolean isSuccess = overviewService.addAmount(amount, userInfo.getId(), UserBillType.COMMSION.value(), UserBillType.COMMSION.desc(), UserInviteRelationTypeConstant.INVITE_PAY);
            if (!isSuccess) {
                log.info("佣金增加余额失败userId = {}, amount = {}", userInfo.getId(), amount);
            }
            UserInfo orderUser = userInfoService.getById(rechargeRecord.getUserId());
            if (orderUser == null) {
                return null;
            }
            map.put("getAmount", String.valueOf(amount));
            map.put("phone", orderUser.getPhone());
            map.put("userId", String.valueOf(userInfo.getId()));
            return map;
        } catch (Exception e) {
            log.error("发放佣金异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        return map;
    }

    /**
     * rank为1代表一级，2代表二级
     *
     * @param rank
     * @return
     */
    private Integer getCommissionRate(int rank) {
        String key = "rate";
        Integer rate = 30;
        if (rank == 2) {
            key = "twoRate";
            rate = 60;
        }
        try {
            String value = configService.getValue(ConfigKey.RECOMMEND);
            JSONObject jsonObject = JSONObject.parseObject(value);
            rate = (Integer) jsonObject.get(key);
        } catch (Exception e) {
            log.error("获取推广佣金比例异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        return rate;
    }


    private RechargeRecord getRechargeRecord(PayParam payParam) {

        String orderNo = IdWorkerUtil.nextStrId();
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setOrderNo(orderNo);
        if (configService.checkWhiteList(payParam.getUserId())) {
            rechargeRecord.setPayAmount(whitePayAmount);
        } else {
            rechargeRecord.setPayAmount(payParam.getPrice());
        }
        rechargeRecord.setType(RechangeRecordEnum.TEN.value());
        rechargeRecord.setOrderDesc(RechangeRecordEnum.TEN.desc());
        rechargeRecord.setUserId(payParam.getUserId());
        rechargeRecord.setStatus(RechargeRecordStatus.prePay);
        rechargeRecord.setInviteId(payParam.getInviteId());
        rechargeRecord.setActivityId(payParam.getActivityId());
        //支付方式，0微信，1支付宝，4小程序，5公众号
        if (PayTypeEnum.ALIPAY.desc().equals(payParam.getType())) {
            rechargeRecord.setPaymentMethod(PayTypeEnum.ALIPAY.value());
        }
        if (PayTypeEnum.WXPAY.desc().equals(payParam.getType())) {
            rechargeRecord.setPaymentMethod(PayTypeEnum.WXPAY.value());
        }
        if (PayTypeEnum.XCX.desc().equals(payParam.getType())) {
            rechargeRecord.setPaymentMethod(PayTypeEnum.XCX.value());
        }
        if (PayTypeEnum.GZH.desc().equals(payParam.getType())) {
            rechargeRecord.setPaymentMethod(PayTypeEnum.GZH.value());
        }
        Date date = new Date();
        rechargeRecord.setCreatedTime(date);
        rechargeRecord.setUpdatedTime(date);
        return rechargeRecord;
    }

    //根据手机号非充值绑定创客
    @Override
    public void bindRecharge(String phone, String inviteId) {
        //查询用户
        UserInfo userInfo = userInfoService.selectUseInfoPhone(phone);
        //绑创客
        Boolean recharge = isRecharge(userInfo);
        //判断是否是创客
        if (!recharge) {
            //非创客创建创客
            RechargeRecord rechargeRecord = getNewRechargeRecord(0, userInfo, inviteId);
            rechargeRecord.setStatus(RechargeRecordStatus.postPay);
            insert(rechargeRecord);
            //记录创客等级信息
            createMaker(phone);
            //发佣金
//            makerCommission(rechargeRecord);
            makerCommissionV340(rechargeRecord);
        }
    }

    //获取创客等级
    private Integer getMakerLevel(String phone) {
        Integer makerLevel = 1;
        UserInfo userInfo = userInfoService.selectUseInfoPhone(phone);
        MemberCardSellRelationLevel memberCardSellRelationLevel = memberCardSellRelationLevelService.getOne(
                new QueryWrapper<MemberCardSellRelationLevel>()
                        .eq(MemberCardSellRelationLevel.USER_ID, userInfo.getId())
        );
        if (Objects.nonNull(memberCardSellRelationLevel) && Objects.nonNull(memberCardSellRelationLevel.getMakerLevel())) {
            makerLevel = memberCardSellRelationLevel.getMakerLevel();
        }
        return makerLevel;
    }

    //创建创客信息
    public UserMaker createMaker(String phone) {
        Integer makerLevel = 1;
        UserInfo userInfo = userInfoService.selectUseInfoPhone(phone);
        String order_no = jdbcTemplate.queryForObject("SELECT mceo.order_no FROM member_card_enable_order mceo join member_card_sell_relation mcsr where mcsr.phone = '" + phone + "' and mceo.`status` = 2 order by mceo.create_time desc limit 1", String.class);
        MemberCardSellRelationLevel memberCardSellRelationLevel = memberCardSellRelationLevelService.getOne(
                new QueryWrapper<MemberCardSellRelationLevel>()
                        .eq(MemberCardSellRelationLevel.ORDER_NO, order_no)
        );
        UserMaker userMaker = new UserMaker();
        userMaker.setUserId(userInfo.getId());
        userMaker.setMakerInviteLevel(0);
        if (Objects.nonNull(memberCardSellRelationLevel) && Objects.nonNull(memberCardSellRelationLevel.getMakerLevel())) {
            makerLevel = memberCardSellRelationLevel.getMakerLevel();
//            userMaker.setMakerLevel(memberCardSellRelationLevel.getMakerLevel());
            userMaker.setLocalProvince(memberCardSellRelationLevel.getLocalProvince());
            userMaker.setLocalCity(memberCardSellRelationLevel.getLocalCity());
        }
        userMaker.setMakerLevel(makerLevel);
        userMakerService.save(userMaker);
        return userMaker;
    }

    @Override
    public void updateInvoiceIsNull(Long id) {
        baseMapper.updateInvoiceIsNull(id);
    }

}
